class Finger
  include Mongoid::Document
  include Mongoid::Timestamps

  default_scope ->{ desc(:created_at) }
  VALID_MARKER = ['invalid', 'pending', 'valid', 'suspect']
  VALID_MARKER.each do |m|
    scope m.to_sym, ->{ where(marker: m) }
  end

  field :uuid, type: String
  # ['valid', 'invalid', 'pending']
  field :marker, type: String, default: 'pending'

  has_many :samples
  belongs_to :task, inverse_of: 'fingers'
  belongs_to :valid_in, class_name: 'Task', inverse_of: 'valid_fingers'

  def reset
    task.results.where(finger1_id: self.id).destroy
    task.results.where(finger2_id: self.id).destroy
    self.marker = 'pending'
    self.save
  end

  def valid_finger?
    marker == 'valid'
  end

  def matched_finger_ids
    self.task.results.where(finger1_id: self.id).map(&:finger2_id).uniq - [self.id.to_s]
  end

  def suspect_finger_id
    results = task.results.where(finger1_id: self.id)
    results.each do |result|
      if result.finger2_id != result.finger1_id && result.marker == 'yes'
        return result.finger2_id
      end
    end

    return nil
  end

  def valid_samples
    Sample.find(self.valid_sample_ids)
  end

  def invalid_sample_ids
    ivs = []
    self.task.results.no.where(finger1_id: self.id, finger2_id: self.id).each do |result|
      ivs << result.sample1_id
    end
    ivs.uniq
  end

  def valid_sample_ids
    vs = []
    self.task.results.yes.where(finger1_id: self.id, finger2_id: self.id).each do |result|
      vs << result.sample1_id
      vs << result.sample2_id
    end
    vs.uniq
  end

  def generate_match
    vs = valid_sample_ids
    sids = self.sample_ids.map(&:to_s)
    pids = self.sample_ids.map(&:to_s) - self.invalid_sample_ids
    sample1 = nil
    sample2 = nil

    # Not enough samples
    if vs.size < self.task.num_of_samples
      if vs.size == 0
        sample1 = Sample.find(pids.sample)
        pids.delete(sample1.id.to_s)
        sample2 = Sample.find(pids.sample)
      else
        sample1 = Sample.find((sids - vs).sample)
        sample2 = Sample.find(vs.sample)
      end
    else
    # Enough samples
      fids = self.task.valid_finger_ids
      mfids = self.matched_finger_ids
      sample1 = Sample.find(vs.first)
      sample2 = Sample.find(Finger.find((fids - mfids).sample).valid_sample_ids.first)
    end
    return sample1, sample2
  end
end
